﻿using System;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.OLE.Interop;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
using System.CodeDom.Compiler;
using VSLangProj80;
using Microsoft.VisualStudio.Designer.Interfaces;
using Microsoft.VisualStudio.TemplateWizard;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.IO;

namespace CodeCounsel.SharePoint.DevTools.ItemTypes
{
    public class SPMetalItemWizard
        : IWizard
    {
        Dictionary<string, string> _customItemProperties;

        public void BeforeOpeningFile(EnvDTE.ProjectItem projectItem)
        {
        }

        public void ProjectFinishedGenerating(EnvDTE.Project project)
        {
        }

        public void ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem)
        {
            if (projectItem != null && _customItemProperties != null)
            {
                if (String.Equals(Path.GetExtension(projectItem.Name), ".xml", StringComparison.InvariantCultureIgnoreCase))
                {
                    EnvDTE.Properties properties = projectItem.Properties;
                    if (properties != null)
                    {
                        foreach (KeyValuePair<string, string> customProperty in _customItemProperties)
                        {
                            EnvDTE.Property property = properties.Item(customProperty.Key);
                            property.Value = customProperty.Value;
                        }
                    }
                }
            }
        }

        public void RunFinished()
        {
        }

        public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary,
            WizardRunKind runKind, object[] customParams)
        {
            _customItemProperties = null;
            if (replacementsDictionary != null)
            {
                if (replacementsDictionary.ContainsKey("$rootname$"))
                {
                    replacementsDictionary.Add("$subnamespace$", MakeNameCompliant(replacementsDictionary["$rootname$"]));
                }
                if (replacementsDictionary.ContainsKey("$itemproperties$"))
                {
                    _customItemProperties = new Dictionary<string, string>();
                    foreach (string propertyName in replacementsDictionary["$itemproperties$"].Split(','))
                    {
                        string propertyValueKey = "$" + propertyName + "$";
                        if (replacementsDictionary.ContainsKey(propertyValueKey))
                        {
                            _customItemProperties.Add(propertyName, replacementsDictionary[propertyValueKey]);
                        }
                    }
                }
            }
        }

        public bool ShouldAddProjectItem(string filePath)
        {
            return true;
        }

        static string MakeNameCompliant(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return string.Empty;
            }
            if (char.IsDigit(name[0]))
            {
                name = "_" + name;
            }
            StringBuilder builder = new StringBuilder(name.Length);
            foreach (char ch in name)
            {
                if (IsValidCharForName(ch))
                {
                    builder.Append(ch);
                }
                else
                {
                    builder.Append('_');
                }
            }
            name = builder.ToString();
            return name;
        }

        static bool IsValidCharForName(char currentChar)
        {
            UnicodeCategory unicodeCategory = char.GetUnicodeCategory(currentChar);
            if (((((unicodeCategory != UnicodeCategory.UppercaseLetter) && (unicodeCategory != UnicodeCategory.LowercaseLetter)) && ((unicodeCategory != UnicodeCategory.OtherLetter) && (unicodeCategory != UnicodeCategory.ConnectorPunctuation))) && (((unicodeCategory != UnicodeCategory.ModifierLetter) && (unicodeCategory != UnicodeCategory.NonSpacingMark)) && ((unicodeCategory != UnicodeCategory.SpacingCombiningMark) && (unicodeCategory != UnicodeCategory.TitlecaseLetter)))) && (((unicodeCategory != UnicodeCategory.Format) && (unicodeCategory != UnicodeCategory.LetterNumber)) && ((unicodeCategory != UnicodeCategory.DecimalDigitNumber) && (currentChar != '.'))))
            {
                return (currentChar == '_');
            }
            return true;
        }
    }
}
